#ifndef _TYPE_TRAIT_HPP_20120411
#define _TYPE_TRAIT_HPP_20120411

#include <string>

namespace mina
{
	template <int v>
		struct Int2Type
		{
			enum { value = v };
		};

	enum
	{
		INT_TYPE      = 0,
		PTR_TYPE      = 1,
		FLOAT_TYPE    = 2,
		STRING_TYPE   = 3,
		USER_TYPE     = 4,
	};

	template <typename _T>
	struct TypeTrait
	{
		enum { base_type = USER_TYPE };
	};

	template <>
		struct TypeTrait<char>
		{
			enum { base_type = INT_TYPE };
		};
	
	template <>
		struct TypeTrait<int8_t>
		{
			enum { base_type = INT_TYPE };
		};

	template <>
		struct TypeTrait<unsigned char>
		{
			enum { base_type = INT_TYPE };
		};
	
	template <>
		struct TypeTrait<int16_t>
		{
			enum { base_type = INT_TYPE };
		};

	template <>
		struct TypeTrait<uint16_t>
		{
			enum { base_type = INT_TYPE };
		};

	template <>
		struct TypeTrait<int32_t>
		{
			enum { base_type = INT_TYPE };
		};

	template <>
		struct TypeTrait<uint32_t>
		{
			enum { base_type = INT_TYPE };
		};

	template <>
		struct TypeTrait<int64_t>
		{
			enum { base_type = INT_TYPE };
		};

	template <>
		struct TypeTrait<uint64_t>
		{
			enum { base_type = INT_TYPE };
		};

	template <typename _T>
		struct TypeTrait<_T*>
		{
			enum { base_type = PTR_TYPE };
		};

	template <>
		struct TypeTrait<float>
		{
			enum { base_type = FLOAT_TYPE };
		};
	
	template <>
		struct TypeTrait<double>
		{
			enum { base_type = FLOAT_TYPE };
		};

	template <>
		struct TypeTrait<long double>
		{
			enum { base_type = FLOAT_TYPE };
		};

	template <>
		struct TypeTrait<std::string>
		{
			enum { base_type = STRING_TYPE };
		};
		
	template <typename _T>
		struct TypeSize
		{
			enum { size = 0x7fffffff };
		};

	template<>
		struct TypeSize<int8_t>
		{
			enum { size = 1 };
		};

	template <>
		struct TypeSize<uint8_t>
		{
			enum { size = 1 };
		};

	template<>
		struct TypeSize<int16_t>
		{
			enum { size = 2 };
		};

	template<>
		struct TypeSize<uint16_t>
		{
			enum { size = 2 };
		};

	template<>
		struct TypeSize<int32_t>
		{
			enum { size = 4 };
		};

	template<>
		struct TypeSize<uint32_t>
		{
			enum { size = 4 };
		};

	template<>
		struct TypeSize<int64_t>
		{
			enum { size = 8 };
		};

	template<>
		struct TypeSize<uint64_t>
		{
			enum { size = 8 };
		};
}

#endif

